// AnnotationTool.cpp : implementation file ============================
// Last Modified : Mikhail Volkov : 090707 =============================

#include "stdafx.h"
#include "ImageLab.h"
#include "AnnotationTool.h"
#include "ChildFrm.h"
#include "io.h"
#include <cstdio>
#include <cstring>
#include <fstream>
#include <sstream>
#include <string>
#include "ImageAnnotation.h"
#include "LinguisticProcessing.h"

// CAnnotationTool dialog
IMPLEMENT_DYNAMIC(CAnnotationTool, CDialog)

CAnnotationTool::CAnnotationTool(CWnd* pParent)
	: CDialog(CAnnotationTool::IDD, pParent)
{
	ASSERT(pParent!=NULL);
	m_Parent = pParent;
	m_nID = CAnnotationTool::IDD;
	::AfxInitRichEdit2();
}

CAnnotationTool::~CAnnotationTool()
{
}

void CAnnotationTool::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAnnotationTool, CDialog)
	ON_LBN_SELCHANGE(IDC_LIST_IMAGELIST, &CAnnotationTool::OnSelectInImageList)
	ON_BN_CLICKED(IDC_BUTTON_NEXTIMAGE, &CAnnotationTool::OnBnClickedNextImage)
	ON_BN_CLICKED(IDC_BUTTON_PREVIOUSIMAGE, &CAnnotationTool::OnBnClickedPreviousImage)
	ON_BN_CLICKED(IDC_BUTTON_LASTIMAGE, &CAnnotationTool::OnBnClickedLastImage)
	ON_BN_CLICKED(IDC_BUTTON_FIRSTIMAGE, &CAnnotationTool::OnBnClickedFirstImage)
	ON_BN_CLICKED(IDC_BUTTON_BROWSE, &CAnnotationTool::OnBnClickedBrowse)
	ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CAnnotationTool::OnBnClickedClear)
	ON_BN_CLICKED(IDC_BUTTON_LOADLOG, &CAnnotationTool::OnBnClickedLoadLog)
	ON_BN_CLICKED(IDC_BUTTON_UPDATELOG, &CAnnotationTool::OnBnClickedSaveLog)
	ON_BN_CLICKED(IDC_RADIO_ANND, &CAnnotationTool::OnBnClickedRadioAnnd)
	ON_BN_CLICKED(IDC_RADIO_NONANND, &CAnnotationTool::OnBnClickedRadioNonAnnd)
	ON_BN_CLICKED(IDC_RADIO_ALL, &CAnnotationTool::OnBnClickedRadioAll)
	ON_BN_CLICKED(IDC_BUTTON_PASTE, &CAnnotationTool::OnBnClickedPastePrevious)
	ON_BN_CLICKED(IDC_BUTTON_UPDATE, &CAnnotationTool::OnBnClickedUpdate)
	ON_BN_CLICKED(IDC_CHECK_FIT, &CAnnotationTool::OnBnClickedCheckFit)
	ON_BN_CLICKED(IDC_CHECK_RENDER, &CAnnotationTool::OnBnClickedCheckRender)
	ON_BN_CLICKED(IDC_CHECK_AUTOSAVE, &CAnnotationTool::OnBnClickedCheckAutoSave)
	ON_COMMAND(ID_ACCEL_NEXTIMAGE, &CAnnotationTool::OnBnClickedNextImage)
	ON_COMMAND(ID_ACCEL_PREVIOUSIMAGE, &CAnnotationTool::OnBnClickedPreviousImage)
	ON_COMMAND(ID_ACCEL_FIRSTIMAGE, &CAnnotationTool::OnBnClickedFirstImage)
	ON_COMMAND(ID_ACCEL_LASTIMAGE, &CAnnotationTool::OnBnClickedLastImage)
	ON_COMMAND(ID_ACCEL_BROWSE, &CAnnotationTool::OnBnClickedBrowse)
	ON_COMMAND(ID_ACCEL_LOADLOG, &CAnnotationTool::OnBnClickedLoadLog)
	ON_COMMAND(ID_ACCEL_SAVELOG, &CAnnotationTool::OnBnClickedSaveLog)
	ON_COMMAND(ID_ACCEL_PASTEPREVIOUS, &CAnnotationTool::OnBnClickedPastePrevious)
	ON_COMMAND(ID_ACCEL_CLEAR, &CAnnotationTool::OnBnClickedClear)
	ON_COMMAND(ID_ACCEL_NEXTTAB, &CAnnotationTool::TabRicheditNextTab)
	ON_COMMAND(ID_IMAGEANNOTATION_DELETEKEYWORD, &CAnnotationTool::DeleteKeyword)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_RICHEDIT, &CAnnotationTool::OnTcnSelchangeTabRichedit)
	ON_CBN_SELCHANGE(IDC_SORTLIST_COMBOBOX, &CAnnotationTool::OnCbnSelchangeSortListComboBox)
	ON_BN_CLICKED(IDC_BUTTON_TEXTPROCESS, &CAnnotationTool::OnBnClickedButtonTextprocess)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_IMAGEANNOTATION_SAVETODATABASE, &CAnnotationTool::OnBnClickedImageannotationSavetodatabase)
	ON_BN_CLICKED(IDC_IMAGEANNOTATION_SEARCHIMAGE, &CAnnotationTool::OnBnClickedImageannotationSearchimage)
END_MESSAGE_MAP()

// Create the dialog
BOOL CAnnotationTool::Create()
{
	BOOL hResult = CDialog::Create(m_nID, m_Parent);
	if(hResult==FALSE)
		return hResult;

	imagesLoaded = false;
	logFileLoaded = false;

	dlg_lprect = new RECT;
	img_lprect = new RECT;
	frm_lprect = new RECT;

	::CAnnotationTool::GetWindowRect(dlg_lprect);
	((CChildFrame*)CAnnotationTool::GetParent())->GetWindowRect(frm_lprect);

	const unsigned MARGIN = 2;
	DLG_DIMX = dlg_lprect->right - dlg_lprect->left;
	DLG_DIMY = dlg_lprect->bottom - dlg_lprect->top;
	FRM_DIMX = frm_lprect->right - frm_lprect->left;
	FRM_DIMY = frm_lprect->bottom - frm_lprect->top;
	IMG_DIMX = FRM_DIMX - DLG_DIMX - 10*MARGIN;
	IMG_DIMY = FRM_DIMY - 53*MARGIN;

	// Align the dialog and child view window
	((CChildFrame*)m_Parent)->MoveWindow(DLG_DIMX+2*MARGIN,MARGIN,IMG_DIMX,IMG_DIMY,true);
	((CChildFrame*)m_Parent)->GetWindowRect(img_lprect);
	::CAnnotationTool::MoveWindow(img_lprect->left-DLG_DIMX-MARGIN,img_lprect->top,DLG_DIMX,DLG_DIMY,true);

	HINSTANCE hInst = AfxGetResourceHandle();
	m_hAccel = ::LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_IMGACCEL));
	ASSERT(m_hAccel);

	CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	m_Edit->SetFocus();

	// Initialise counters
	imagesLoaded = false;
	logFileLoaded = false;
	m_Total = 0;
	m_Cur = -1;

	// Handlers for tab control:
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	m_TabCtrl->InsertItem(0, _T("Caption"));
	m_TabCtrl->InsertItem(1, _T("Reference"));
	m_TabCtrl->InsertItem(2, _T("Reminds me of.."));
	m_TabLastSel = m_TabCtrl->GetCurSel();

	// Handlers for combo box
	CComboBox* m_ComboBox = (CComboBox*)CAnnotationTool::GetDlgItem(IDC_SORTLIST_COMBOBOX);
	m_ComboBox->InsertString(0, _T("Directory structure"));
	m_ComboBox->InsertString(1, _T("Alphabetical order"));
	m_ComboBox->InsertString(2, _T("Date modified"));
	m_ComboBox->InsertString(3, _T("Caption size"));
	m_ComboBox->SetCurSel(0);

	// Initialise browsing mode
	CButton* m_Button = (CButton*)CAnnotationTool::GetDlgItem(IDC_RADIO_ALL);
	m_Button->SetCheck(BST_CHECKED);
	browsingMode = All;

	// Pre-define render off by default
	CButton* m_RenderCheck = (CButton*)CAnnotationTool::GetDlgItem(IDC_CHECK_RENDER);
	m_RenderCheck->EnableWindow(FALSE);
	isRender = false;

	// Pre-define auto-save on by default
	CButton* m_AutoSaveCheck = (CButton*)CAnnotationTool::GetDlgItem(IDC_CHECK_AUTOSAVE);
	m_AutoSaveCheck->SetCheck(1);

	//Initialize the text processing
	textprocess = NULL;
	searchimage = NULL;
	return hResult;
}
//
//BOOL CAnnotationTool::PreTranslateMessage(MSG* pMsg) 
//{
//    if(m_hAccel)
//	{
//		if(::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
//			return(TRUE);
//	}	
//	return CDialog::PreTranslateMessage(pMsg);
//}

// Filesystem functions:
void CAnnotationTool::OnBnClickedBrowse()
{
	// Parameters for a folder view
	LPWSTR lpszDir = new WCHAR[_MAX_PATH];
	LPWSTR buffer = new WCHAR[_MAX_PATH];

	::OleInitialize(NULL);
	BROWSEINFO br_info;
	memset(&br_info, 0, sizeof(br_info));

	// Browse the path for images
	br_info.ulFlags = BIF_USENEWUI;
	br_info.hwndOwner = NULL;
	br_info.lpszTitle = _T("Please Select a Folder for Images");

	LPITEMIDLIST pidl;
	pidl = ::SHBrowseForFolder(&br_info);

	if(pidl != NULL)
	{
		// Create a buffer to store the path and then get the path
		if(::SHGetPathFromIDList(pidl, lpszDir) != 0)
		{
			// Set the string value
		}
		// Free the item ID list
		CoTaskMemFree(pidl);
	}
	else
	{
		::AfxMessageBox(CString("No folder selected"), MB_OK, 0);
		return;
	}
	::OleUninitialize();
	
	// Load the folder
	::CAnnotationTool::LoadAFolder(CString(lpszDir));
	return;
}

void CAnnotationTool::BuildFileList(string rootDir, list<FILELIST>& tree)
{
	//Construct a list of folders
	vector<string> listoffolders;
	listoffolders.push_back(rootDir);

	unsigned int i=0;
	do
	{
		//Construct the searching
		_finddata_t data;
		string fpath = listoffolders[i]+"\\*.*";
		long handle = (long)_findfirst(fpath.c_str(), &data);
		//If something found
		if(handle >= 0)
		{
			FILELIST eachfilelist;
			eachfilelist.dir = listoffolders[i];
			do
			{
				if(data.attrib & _A_SUBDIR)	//If it is a folder, push it to listoffolders
				{
					if(strcmp(data.name, ".")!=0 && strcmp(data.name, "..")!=0)
						listoffolders.push_back(listoffolders[i] + "\\" + data.name);
				}
				else	//If it is a file, push it to list of files
				{
					eachfilelist.files.push_back(data.name);
					eachfilelist.times.push_back(data.time_write);
				}
			}while(_findnext(handle, &data)==0);
			tree.push_back(eachfilelist);
		}
		_findclose(handle);
		i++;
	}while(i<listoffolders.size());

	return;

	//if(handle >= 0)
	//{
	//	FILELIST eachfilelist;
	//}

	//_finddata_t data;
	//string fpath = rootDir + "\\*.*";
	//long handle = (long)_findfirst(fpath.c_str(), &data);
	//if (handle >= 0)
	//{
	//	FILELIST eachFileList;
	//	eachFileList.dir = rootDir;
 //       do {
	//		if (data.attrib & _A_SUBDIR)
	//		{
	//			if (strcmp(data.name,".") != 0 && strcmp(data.name,"..") != 0)
	//			{
	//				fpath = rootDir + "\\" + data.name;
	//				::CAnnotationTool::BuildFileList(fpath, tree); // Recursion to search through subdirectories
	//			}
	//		}
	//		else
	//		{
	//			(eachFileList.files).push_back(data.name); // Add entry to the filelist
	//			(eachFileList.times).push_back(data.time_write); // Add last write time to the filelist
	//		}
	//	} while (_findnext(handle,&data) == 0);
	//	tree.push_back(eachFileList);
	//	_findclose(handle);
	//}
	//return;
}

void CAnnotationTool::SortFileList(sortModes SORT_OPTION, size_t range)
{
	m_Cur = -1;
	m_Enum.clear();
	m_Count = 0;
	if (range != 1)
	{
		int swap = 0; // Swapping index
		switch(SORT_OPTION)
		{
		case byDirStruct: // Sort by original directory structure
			{
				// Find swapping index
				for (unsigned i=1; i<range; i++)
					if (m_Normal[i] > m_Normal[swap])
						swap = i;
			}
			break;
		case byAlphabet: // Sort by alphabetical order
			{
				// Find swapping index
				for (unsigned i=1; i<range; i++)
					if (!bf.StrAlphaCompare(m_FileName[i], m_FileName[swap]))
						swap = i;	
			}
			break;
		case byModified: // Sort by __time64_t modified
			{
				// Find swapping index
				for (unsigned i=1; i<range; i++)
					if ((int)m_FileModified[i] < (int)m_FileModified[swap])
						swap = i;	
			}
			break;
		case byCaption: // Sort by caption size
			{
				// Find swapping index
				for (unsigned i=1; i<range; i++)
				{
					std::string temp_filepath_i = bf.Truncate(m_FileList[i],4) + ".txt";
					std::string temp_filepath_swap = bf.Truncate(m_FileList[swap],4) + ".txt";
					if (bf.CharsInFile(temp_filepath_i) < bf.CharsInFile(temp_filepath_swap))
						swap = i;
				}
			}
			break;
		default:
			return;
		}

		// Apply swapping algorithm to m_FileList and to all parallel vectors
		string templist = m_FileList[swap];
		m_FileList[swap] = m_FileList[range-1];
		m_FileList[range-1] = templist;
		//m_FileList.push_back(m_FileList[swap]);
		//m_FileList[swap] = m_FileList[range-1];
		//m_FileList[range-1] = m_FileList[m_FileList.size()-1];
		//m_FileList.pop_back();

		templist = m_FileName[swap];
		m_FileName[swap] = m_FileName[range-1];
		m_FileName[range-1] = templist;
		//m_FileName.push_back(m_FileName[swap]);
		//m_FileName[swap] = m_FileName[range-1];
		//m_FileName[range-1] = m_FileName[m_FileName.size()-1];
		//m_FileName.pop_back();

		__time64_t temptime = m_FileModified[swap];
		m_FileModified[swap] = m_FileModified[range-1];
		m_FileModified[range-1] = temptime;
		//m_FileModified.push_back(m_FileModified[swap]);
		//m_FileModified[swap] = m_FileModified[range-1];
		//m_FileModified[range-1] = m_FileModified[m_FileModified.size()-1];
		//m_FileModified.pop_back();

		int tempint = m_Normal[swap];
		m_Normal[swap] = m_Normal[range-1];
		m_Normal[range-1] = tempint;
		//m_Normal.push_back(m_Normal[swap]);
		//m_Normal[swap] = m_Normal[range-1];
		//m_Normal[range-1] = m_Normal[m_Normal.size()-1];
		//m_Normal.pop_back();

		::CAnnotationTool::SortFileList(SORT_OPTION, --range); // Recursive call
	}
	else
		::CAnnotationTool::UpdateList();
	return;
}

void CAnnotationTool::LoadAFolder(CString m_FolderPath)
{
	// Initialization
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	m_Count = 0;

	// Build the list and load the root directory
	CT2CA pszConvertedString(m_FolderPath);
	string rootDir(pszConvertedString);
	::CAnnotationTool::BuildFileList(rootDir, tree);

	// Construct the list into the dialog
	list<FILELIST>::iterator iter = tree.begin();
	vector<string>::iterator it;
	vector<string>::iterator itstart = m_FileList.begin();
	vector<string>::iterator itend = m_FileList.end();
	while(iter!=tree.end())
	{
		for(int i=0; i<(int)iter->files.size(); i++)
		{
			// Validate if it is an image or not and push the files in a folder into the filelist
			if((int)iter->files[i].size()>4)
			{
				// Get the file extension
				string FileExtension(&(iter->files[i].c_str()[iter->files[i].size()-4]));

				// Compare with the image extensions
				if(FileExtension == ".bmp" || FileExtension == ".BMP" ||
				   FileExtension == ".jpg" || FileExtension == ".JPG" ||
				   FileExtension == ".tif" || FileExtension == ".TIF" ||
				   FileExtension == ".gif" || FileExtension == ".GIF" ||
				   FileExtension == ".png" || FileExtension == ".PNG")
				{
					// Check if image already present in current view list
					bool isDuplicate = false;
					for (it=itstart; it!=itend; it++)
						if (*it == (iter->dir + "\\" + iter->files[i]))
						{
							isDuplicate = true;
							break;
						}

					if (!isDuplicate)
					{
						m_FileList.push_back(iter->dir + "\\" + iter->files[i]);
						m_FileName.push_back(iter->files[i]);
						m_FileModified.push_back(iter->times[i]);

						// Push the file into the list
						CString filename(iter->files[i].c_str());
						m_ListBox->AddString(filename);
						m_Count ++;
					}
				}
			}
		}
		iter ++;
	}

	// Check if there are images loaded
	if(m_Count == 0)
	{
		::AfxMessageBox(CString("No images found!"), MB_OK, 0);
		return;
	}

	// Enumerate images
	while (m_Total < m_FileList.size())
	{
		m_Enum.push_back(m_Total);
		m_Normal.push_back(m_Total);
		m_Total++;
	}

	// Update counter
	CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_COUNTER);
	CString m_Count_CStr (bf.IntToString(m_Count).c_str());
	CString m_Total_CStr (bf.IntToString(m_Total).c_str());
	CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
	m_Edit->SetWindowTextW(m_Items);

	// Set flags
	imagesLoaded = (m_Total!=0)?true:false;

	return;
}

void CAnnotationTool::LoadLogFile()
{
	// Dialog to select and load logfile
	CFile cfile;
	CString strFilter;
	strFilter = "ImageNote Logfile (*.ill)|*.ill||";

	// Display the dialog
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_EXPLORER,strFilter);
	if (dlg.DoModal()!=IDOK)
		return;
	CString logFilePath = dlg.m_ofn.lpstrFile;

	// Convert CString to std::string
	CT2CA temp_logFilePath(logFilePath);
	std::string std_logFilePath(temp_logFilePath);

/****************************************************************
*																*
*	// Parse logfile and store previous entries in a vector		*
*	std::vector<std::string> previousEntries(0);				*
*	std::ifstream logFile;										*
*	logFile.open(std_logFilePath.c_str(),std::ios::in);			*
*	std::string temp;											*	
*	while(std::getline(logFile,temp))							*
*		previousEntries.push_back(temp);						*		
*	logFile.close();											*
*																*	
****************************************************************/

	// Parse logfile and store previous entries in a vector
	std::vector<std::string> previousEntries(0);
	std::vector<__time64_t> previousModified(0);
	std::ifstream logFile;
	logFile.open(std_logFilePath.c_str(),std::ios::in);
	std::string temp;
	unsigned long temp64;
	while (!logFile.eof())
	{
		if (logFile.peek() != '#')
		{
			logFile >> temp64;
			while (!isalnum(logFile.peek()) && !logFile.eof())
				logFile.ignore();
			std::getline(logFile,temp);
			previousModified.push_back((__time64_t)temp64);
			previousEntries.push_back(temp);
		}
		else
			logFile.ignore(65536,'\n');
	}
	logFile.close();

	// Open up and display the images stored in the vector
	m_Count = 0;
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	std::vector<std::string>::iterator iter = previousEntries.begin();
	std::vector<__time64_t>::iterator iter64 = previousModified.begin();
	while (iter!=previousEntries.end() && iter64!=previousModified.end())
	{
		// Validate if it is an image or not
		if(((int)iter->size())>4)
		{

			// Get the file extension
			CStringA FileExtCString(iter->c_str());
			char* temp = FileExtCString.GetBuffer();
			string FileExtension(&temp[(int)FileExtCString.GetLength()-4]);

			// Compare with the image extensions
			if(FileExtension == ".bmp" || FileExtension == ".BMP" ||
			   FileExtension == ".jpg" || FileExtension == ".JPG" ||
			   FileExtension == ".tif" || FileExtension == ".TIF" ||
			   FileExtension == ".gif" || FileExtension == ".GIF" ||
			   FileExtension == ".psd" || FileExtension == ".PSD" )
			{

				// Check if image already present in current view list
				bool isDuplicate = false;
				vector<string>::iterator it;
				for (it=m_FileList.begin(); it!=m_FileList.end(); it++)
					if (*it == *iter)
						isDuplicate = true;

				if (!isDuplicate)
				{
					// Push full path into filelist
					m_FileList.push_back(*iter);
					std::string tempFileName = iter->substr(int(iter->find_last_of("\\"))+1,(int(iter->size())-int(iter->find_last_of("/\\"))-1));
					m_FileName.push_back(tempFileName);
					m_FileModified.push_back(*iter64);

					// Push the file into the list
					CString filename(tempFileName.c_str());
					m_ListBox->AddString(filename);
					m_Count ++;
				}
			}
		}
	iter++;
	iter64++;
	}

	// Check if there are images loaded
	if(m_Count == 0)
	{
		::AfxMessageBox(CString("No images found!"), MB_OK, 0);
		return;
	}

	// Enumerate images
	while (m_Total < m_FileList.size())
	{
		m_Enum.push_back(m_Total);
		m_Normal.push_back(m_Total);
		m_Total++;
	}

	// Update counter
	CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_COUNTER);
	CString m_Count_CStr (bf.IntToString(m_Count).c_str());
	CString m_Total_CStr (bf.IntToString(m_Total).c_str());
	CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
	m_Edit->SetWindowTextW(m_Items);

	// Set flags
	imagesLoaded = (m_Total!=0)?true:false;
	logFileLoaded = (m_Total!=0)?true:false;

	::CAnnotationTool::UpdateList();
	return;
}

void CAnnotationTool::CreateLogFile(vector<string> m_FileList) 
{
	if (m_FileList.empty())
	{
		::AfxMessageBox(CString("There are no images to log!"), MB_OK, 0);
		return;
	}
	std::ofstream newLogFile;

	// Create a dialog to save new log file
	CFile cfile;
	HRESULT hResult;
	CString strFilter;
	strFilter = "ImageNote Logfile (*.ill)|*.ill||";

	// Display the dialog
	CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,strFilter);
	hResult = (int)dlg.DoModal();
	if (FAILED(hResult))
		return;
	CString newLogFilePath = dlg.m_ofn.lpstrFile;

	// Convert CString to std::string
	CT2CA temp_newLogFilePath(newLogFilePath);
	std::string std_newLogFilePath(temp_newLogFilePath);

	// Add on the right extn if use did not enter it
	if (std_newLogFilePath.substr(std_newLogFilePath.size()-4,4) != ".ill")
		std_newLogFilePath += ".ill";

/********************************************************************
*																	*
*	// Remove old logfile and create a new one						*
*	remove(std_newLogFilePath.c_str());								*
*	newLogFile.open(std_newLogFilePath.c_str(),std::ios::out);		*
*	for (unsigned i=0; i<m_FileList.size(); i++)					*
*		newLogFile << m_FileList.at(i) << std::endl;				*
*	newLogFile.close();												*
*																	*
********************************************************************/

	// Remove old logfile and create a new one
	remove(std_newLogFilePath.c_str());
	newLogFile.open(std_newLogFilePath.c_str(),std::ios::out);
	newLogFile << "# ImageLab x.xx Logfile, " << std_newLogFilePath << "\n";
	time_t TIME = time(0);
	newLogFile << "# Created on " << ctime(&TIME);
	newLogFile << "#\n#\n";
	for (unsigned i=0; i<m_FileList.size(); i++)
	{
		newLogFile << m_FileModified.at(i) << "\t || ";
		newLogFile << m_FileList.at(i) << std::endl;
	}
	newLogFile.close();
}

// Image List functions:
void CAnnotationTool::UpdateList()
{
	switch(browsingMode) 
	{
		case New:
			// Redundant
			break;
		case Old:
			// Redundant
			break;
		case Annd:
			::CAnnotationTool::OnBnClickedRadioAnnd();
			break;
		case NonAnnd:
			::CAnnotationTool::OnBnClickedRadioNonAnnd();
			break;
		case All:
			::CAnnotationTool::OnBnClickedRadioAll();
			break;
	}
	return;
}

void CAnnotationTool::OnSelectInImageList()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);

	if (imagesLoaded)
	{
		::CAnnotationTool::UpdateTextEntry();

		// Reset tabs to caption
		CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
		m_TabCtrl->SetCurSel(0);
		m_TabLastSel = 0;

		// Get the selected text and its index
		m_Cur = m_ListBox->GetCurSel();
		if(m_Cur==CB_ERR)
			return;
		CString filepath(m_FileList[m_Enum.at(m_Cur)].c_str());
		CString filename(m_FileName[m_Enum.at(m_Cur)].c_str());

		((CChildFrame*)m_Parent)->m_wndView.OnImageOpen(filepath, filename);
		::CAnnotationTool::OpenRichEdit(filepath);

		// Change the Editbox
		CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
		m_Edit->SetWindowTextW(CString(filepath));

		::CAnnotationTool::FocusOnRichEdit();
	}
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}
void CAnnotationTool::OnBnClickedNextImage()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	
	// Return if no image selected
	if (m_ListBox->GetCurSel() == LB_ERR)
		return;

	if (imagesLoaded)
	{
		::CAnnotationTool::UpdateTextEntry();

		if(m_Cur==CB_ERR)
			return;
		
		if(m_Enum[m_Cur]<m_Enum.back())
			m_Cur++;
		else
			return;

		// Reset tabs to caption
		CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
		m_TabLastSel = 0;

		// Move to the current pointer
		CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
		m_ListBox->SetCurSel(m_Cur);

		// Retrieve the text
		CString filepath(m_FileList[m_Enum.at(m_Cur)].c_str());
		CString filename(m_FileName[m_Enum.at(m_Cur)].c_str());
		((CChildFrame*)m_Parent)->m_wndView.OnImageOpen(filepath, filename);
		::CAnnotationTool::OpenRichEdit(filepath);

		// Change the Editbox
		CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
		m_Edit->SetWindowTextW(CString(filepath));

		::CAnnotationTool::FocusOnRichEdit();
	}
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}

void CAnnotationTool::OnBnClickedPreviousImage()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	
	// Return if no image selected
	if (m_ListBox->GetCurSel() == LB_ERR)
		return;

	if (imagesLoaded)
	{
		::CAnnotationTool::UpdateTextEntry();

		if(m_Cur==CB_ERR)
			return;

		if(m_Enum.at(m_Cur)>m_Enum.front())
			m_Cur--;
		else
			return;

		// Reset tabs to caption
		CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
		m_TabCtrl->SetCurSel(0);
		m_TabLastSel = 0;

		// Move to the current pointer
		CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
		m_ListBox->SetCurSel(m_Cur);

		//Retrieve the text
		CString filepath(m_FileList[m_Enum.at(m_Cur)].c_str());
		CString filename(m_FileName[m_Enum.at(m_Cur)].c_str());
		((CChildFrame*)m_Parent)->m_wndView.OnImageOpen(filepath, filename);
		::CAnnotationTool::OpenRichEdit(filepath);

		// Change the Editbox
		CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
		m_Edit->SetWindowTextW(CString(filepath));

		::CAnnotationTool::FocusOnRichEdit();
	}
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}

void CAnnotationTool::OnBnClickedLastImage()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	
	// Return if no image selected
	if (m_ListBox->GetCurSel() == LB_ERR)
		return;

	if (imagesLoaded)
	{
		::CAnnotationTool::UpdateTextEntry();
		
		if(m_Cur==CB_ERR)
			return;

		// Reset tabs to caption
		CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
		m_TabCtrl->SetCurSel(0);
		m_TabLastSel = 0;

		// Move to the current pointer
		m_ListBox->SetCurSel((int)m_Enum.size()-1);
		m_Cur = (int)m_Enum.size()-1;

		// Retrieve the text
		CString filepath(m_FileList[int(m_Enum.size()-1)].c_str());
		CString filename(m_FileName[int(m_Enum.size()-1)].c_str());
		((CChildFrame*)m_Parent)->m_wndView.OnImageOpen(filepath, filename);
		::CAnnotationTool::OpenRichEdit(filepath);

		// Change the Editbox
		CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
		m_Edit->SetWindowTextW(CString(filepath));

		::CAnnotationTool::FocusOnRichEdit();
	}
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}

void CAnnotationTool::OnBnClickedFirstImage()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	
	// Return if no image selected
	if (m_ListBox->GetCurSel() == LB_ERR)
		return;

	if (imagesLoaded)
	{
		::CAnnotationTool::UpdateTextEntry();

		if(m_Cur==CB_ERR)
			return;

		// Reset tabs to caption
		CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
		m_TabCtrl->SetCurSel(0);
		m_TabLastSel = 0;

		// Move to the current pointer
		m_ListBox->SetCurSel(0);
		m_Cur = 0;

		// Retrieve the text
		CString filepath(m_FileList[0].c_str());
		CString filename(m_FileName[0].c_str());
		((CChildFrame*)m_Parent)->m_wndView.OnImageOpen(filepath, filename);
		::CAnnotationTool::OpenRichEdit(filepath);

		// Change the Editbox
		CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
		m_Edit->SetWindowTextW(CString(filepath));

		::CAnnotationTool::FocusOnRichEdit();
	}
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}

// Caption Functions:
void CAnnotationTool::FocusOnRichEdit()
{
	CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	m_Edit->SetActiveWindow();
	m_Edit->SetFocus();
	return;
}

void CAnnotationTool::OpenRichEdit(CString m_FilePath)
{
	// Load the rich edit
	CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);

	// Open the file
	m_FilePath.Truncate((int)m_FilePath.GetLength()-4);

	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	switch(m_TabCtrl->GetCurSel())
	{
	case Reference:
		m_FilePath += ".reference";
		break;
	case Reminds:
		m_FilePath += ".remindsof";
		break;
	case Caption:
	default:
		break;
	}

	m_FilePath += ".txt";

	CFile m_File;
	CFileException e;

	// If cannot find the file, create a new one
	if(!m_File.Open(m_FilePath, CFile::modeRead, &e))
	{
		m_Edit->SetWindowTextW(CString(""));
		return;
	}

	// Read the content of the file
	char* m_FileContent = (char*)malloc(sizeof(char)*(UINT)m_File.GetLength());
	UINT nByteRead = m_File.Read(m_FileContent, (UINT)m_File.GetLength());

	// Assign the content to the rich edit and Assign the content to the text processing dialog
	m_Edit->SetWindowTextW(CString(m_FileContent, (int)m_File.GetLength()));
	if(textprocess!=NULL)
		textprocess->AssignStringFreeText(CString(m_FileContent, (int)m_File.GetLength()));

	m_File.Close();
	::CAnnotationTool::GotoDlgCtrl(::CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION));

	/* Inseart code here for hanlding the event of open the keyword from text file */

	return;
}

void CAnnotationTool::UpdateTextEntry()
{
	if (m_Cur==-1)
		return;

	// Retrieve the checkbox status
	CButton* m_Button = (CButton*)CAnnotationTool::GetDlgItem(IDC_CHECK_AUTOSAVE);
	int isAutoSaveChecked = m_Button->GetCheck();

	// If auto-save is selected
	if(isAutoSaveChecked == 1)
	{
		// Check other exceptions
		if (!m_Enum.empty() /*&& m_ListBox->GetCurSel()!=LB_ERR*/)
		{
			// Save the text to the file and retrieve the new content
			CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
			TCHAR* m_CurText = (TCHAR*)malloc(sizeof(TCHAR)*(m_Edit->GetWindowTextLengthW()+1));
			m_Edit->GetWindowTextW(m_CurText, m_Edit->GetWindowTextLengthW()+1);
			// Retrieve the current filename
			CString filePath(m_FileList[m_Enum.at(m_Cur)].c_str());
			filePath.Truncate((int)filePath.GetLength()-4);
			CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
			switch(m_TabLastSel)
			{
			case Reference:
				filePath += ".reference";
				break;
			case Reminds:
				filePath += ".remindsof";
				break;
			case Caption:
			default:
				break;
			}
			filePath += ".txt";

			// Remove the file and create a new one
			CT2CA temp_filePath(filePath);
			std::string std_filePath(temp_filePath);
			remove (std_filePath.c_str());

			// Write the content to file
			CFile m_File;
			CFileException e;
			if(!m_File.Open(filePath, CFile::modeRead|CFile::modeWrite, &e)) // If the file does not exist
			{
				try
				{
					m_File.Open(filePath, CFile::modeCreate|CFile::modeWrite); // Create the file
				}
				catch(CException* e)
				{
					e->ReportError();		// If fail to create, report the error
					return;
				}
			}
			CStringA pszConvertedText(m_CurText, m_Edit->GetWindowTextLengthW());
			m_LastContent = CString(pszConvertedText);
			m_File.Write(pszConvertedText.GetBuffer(), (UINT)m_Edit->GetWindowTextLengthW());
			m_File.Close();
		}
	}

	/* Insear here the code for handling saving the keywords into text file */

	return;
}

// Buttons:
void CAnnotationTool::OnBnClickedClear()
{

	CAnnotationTool::UpdateTextEntry();

	// Destroy old image
	((CChildFrame*)m_Parent)->m_wndView.imgOriginal.Destroy();
	((CChildFrame*)m_Parent)->m_wndView.Invalidate();
	((CChildFrame*)m_Parent)->m_wndView.UpdateWindow();

	// Clear dialog
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	CEdit* m_Edit1 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	CEdit* m_Edit2 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
	CEdit* m_Edit3 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_COUNTER);
	m_ListBox->ResetContent();
	m_Edit1->SetWindowTextW(CString(""));
	m_Edit2->SetWindowTextW(CString(""));
	m_Edit3->SetWindowTextW(CString(""));
	m_Cur = -1;
	m_Total = 0;
	m_FileList.clear();
	m_FileName.clear();
	m_Enum.clear();
	tree.clear();
	imagesLoaded = false;
	logFileLoaded = false;
	return;
}

void CAnnotationTool::OnBnClickedLoadLog()
{
	::CAnnotationTool::LoadLogFile();
	return;
}

void CAnnotationTool::OnBnClickedSaveLog()
{
	if (imagesLoaded)
		::CAnnotationTool::CreateLogFile(m_FileList);
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}

void CAnnotationTool::OnBnClickedRadioAnnd()
{
	browsingMode = Annd;

	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel() != LB_ERR)
		::CAnnotationTool::UpdateTextEntry();

	// Reset tabs to caption
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	m_TabCtrl->SetCurSel(0);
	m_TabLastSel = 0;

	CEdit* m_Edit1 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	CEdit* m_Edit2 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
	CEdit* m_Edit3 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_COUNTER);

	m_ListBox->ResetContent();
	m_Edit1->SetWindowTextW(CString(""));
	m_Edit2->SetWindowTextW(CString(""));
	m_Edit3->SetWindowTextW(bf.douTostr(double(0)));

	m_Cur = -1;
	m_Enum.clear();
	m_Count = 0;
	vector<string>::iterator iter = m_FileList.begin();
	for (unsigned i=0; i<m_FileList.size(); i++)
	{
		string annotationFileName = bf.Truncate(*iter,4) + ".txt";
		if (!bf.FileIsEmpty(annotationFileName.c_str()))
		{
			std::string tempFileName = iter->substr(int(iter->find_last_of("\\"))+1,(int(iter->size())-int(iter->find_last_of("/\\"))-1));
			CString filename(tempFileName.c_str());
			m_ListBox->AddString(filename);
			m_Enum.push_back(i);
			m_Count ++;
		}
		iter++;
		CString m_Count_CStr (bf.IntToString(m_Count).c_str());
		CString m_Total_CStr (bf.IntToString(m_Total).c_str());
		CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
		m_Edit3->SetWindowTextW(m_Items);
	}

	// Set counter
	CString m_Count_CStr (bf.IntToString(m_Count).c_str());
	CString m_Total_CStr (bf.IntToString(m_Total).c_str());
	CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
	m_Edit3->SetWindowTextW(m_Items);

	// Destroy old image
	((CChildFrame*)m_Parent)->m_wndView.imgOriginal.Destroy();
	((CChildFrame*)m_Parent)->m_wndView.Invalidate();
	((CChildFrame*)m_Parent)->m_wndView.UpdateWindow();

	return;
}
void CAnnotationTool::OnBnClickedRadioNonAnnd()
{
	browsingMode = NonAnnd;

	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel() != LB_ERR)
		::CAnnotationTool::UpdateTextEntry();

	// Reset tabs to caption
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	m_TabCtrl->SetCurSel(0);
	m_TabLastSel = 0;

	CEdit* m_Edit1 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	CEdit* m_Edit2 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
	CEdit* m_Edit3 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_COUNTER);

	m_ListBox->ResetContent();
	m_Edit1->SetWindowTextW(CString(""));
	m_Edit2->SetWindowTextW(CString(""));
	m_Edit3->SetWindowTextW(bf.douTostr(0));

	m_Cur = -1;
	m_Enum.clear();
	m_Count = 0;
	vector<string>::iterator iter = m_FileList.begin();
	for (unsigned i=0; i<m_FileList.size(); i++)
	{
		string annotationFileName = bf.Truncate(*iter,4) + ".txt";
		if (bf.FileIsEmpty(annotationFileName.c_str()))
		{
			std::string tempFileName = iter->substr(int(iter->find_last_of("\\"))+1,(int(iter->size())-int(iter->find_last_of("/\\"))-1));
			CString filename(tempFileName.c_str());
			m_ListBox->AddString(filename);
			m_Enum.push_back(i);
			m_Count ++;
		}
		iter++;
		CString m_Count_CStr (bf.IntToString(m_Count).c_str());
		CString m_Total_CStr (bf.IntToString(m_Total).c_str());
		CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
		m_Edit3->SetWindowTextW(m_Items);
	}

	// Set counter
	CString m_Count_CStr (bf.IntToString(m_Count).c_str());
	CString m_Total_CStr (bf.IntToString(m_Total).c_str());
	CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
	m_Edit3->SetWindowTextW(m_Items);

	// Destroy old image
	((CChildFrame*)m_Parent)->m_wndView.imgOriginal.Destroy();
	((CChildFrame*)m_Parent)->m_wndView.Invalidate();
	((CChildFrame*)m_Parent)->m_wndView.UpdateWindow();

	return;
}

void CAnnotationTool::OnBnClickedRadioAll()
{
	browsingMode = All;

	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel() != LB_ERR)
		::CAnnotationTool::UpdateTextEntry();

	// Reset tabs to caption
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	m_TabCtrl->SetCurSel(0);
	m_TabLastSel = 0;

	CEdit* m_Edit1 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	CEdit* m_Edit2 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_FOLDERPATH);
	CEdit* m_Edit3 = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_COUNTER);

	m_ListBox->ResetContent();
	m_Edit1->SetWindowTextW(CString(""));
	m_Edit2->SetWindowTextW(CString(""));
	m_Edit3->SetWindowTextW(bf.douTostr(0));

	m_Cur = -1;
	m_Enum.clear();
	m_Count = 0;
	vector<string>::iterator iter = m_FileList.begin();
	for (unsigned i=0; i<m_FileList.size(); i++)
	{
		std::string tempFileName = iter->substr(int(iter->find_last_of("\\"))+1,(int(iter->size())-int(iter->find_last_of("/\\"))-1));
		CString filename(tempFileName.c_str());
		m_ListBox->AddString(filename);
		m_Enum.push_back(i);
		m_Count ++;
		iter++;
	}

	// Set counter
	CString m_Count_CStr (bf.IntToString(m_Count).c_str());
	CString m_Total_CStr (bf.IntToString(m_Total).c_str());
	CString m_Items = m_Count_CStr + " of " + m_Total_CStr;
	m_Edit3->SetWindowTextW(m_Items);

	// Destroy old image
	((CChildFrame*)m_Parent)->m_wndView.imgOriginal.Destroy();
	((CChildFrame*)m_Parent)->m_wndView.Invalidate();
	((CChildFrame*)m_Parent)->m_wndView.UpdateWindow();

	return;
}

void CAnnotationTool::OnBnClickedPastePrevious()
{
	CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
	m_Edit->SetWindowTextW(m_LastContent);
	return;
}

void CAnnotationTool::OnBnClickedUpdate()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel() == LB_ERR)
		return;

	if (imagesLoaded)
	{
		// Save the text to the file and retrieve the new content
		CEdit* m_Edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
		TCHAR* m_CurText = (TCHAR*)malloc(sizeof(TCHAR)*m_Edit->GetWindowTextLengthW());
		m_Edit->GetWindowTextW(m_CurText, m_Edit->GetWindowTextLengthW()+1);

		// Write the content to file
		CFile m_File;

		// Retrieve the current filename
		CString filePath(m_FileList[m_Enum.at(m_Cur)].c_str());
		filePath.Truncate((int)filePath.GetLength()-4);

		CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
		switch(m_TabCtrl->GetCurSel())
		{
		case Reference:
			filePath += ".reference";
			break;
		case Reminds:
			filePath += ".remindsof";
			break;
		case Caption:
		default:
			break;
		}

		filePath += ".txt";

		// Remove the file and create a new one
		CT2CA temp_filePath(filePath);
		std::string std_filePath(temp_filePath);
		remove (std_filePath.c_str());

		// Open the file and save
		CFileException e;
		if(!m_File.Open(filePath, CFile::modeRead|CFile::modeWrite, &e)) // If the file does not exist
		{
			try
			{
				m_File.Open(filePath, CFile::modeCreate|CFile::modeWrite); // Create the file
			}
			catch(CException* e)
			{
				e->ReportError(); // If fail to create, report the error
				return;
			}
		}
		CStringA pszConvertedText(m_CurText, m_Edit->GetWindowTextLengthW());
		m_LastContent = CString(pszConvertedText);
		m_File.Write(pszConvertedText.GetBuffer(), (UINT)m_Edit->GetWindowTextLengthW());
		m_File.Close();

		::CAnnotationTool::UpdateList();
	}
	else
		::AfxMessageBox(CString("No images loaded!"), MB_OK, 0);
	return;
}
void CAnnotationTool::OnBnClickedCheckFit()
{
	CButton* m_Button = (CButton*)CAnnotationTool::GetDlgItem(IDC_CHECK_FIT);
	int isFitChecked = m_Button->GetCheck();

	CButton* m_RenderCheck = (CButton*)CAnnotationTool::GetDlgItem(IDC_CHECK_RENDER);

	
	if (isFitChecked == 1) // Fit to size is selected
	{
		((CChildFrame*)m_Parent)->m_wndView.ResizeImage(IMG_DIMX, IMG_DIMY, true);
		m_RenderCheck->EnableWindow(TRUE);
	}
	else				// Fit to size is not selected
	{
		((CChildFrame*)m_Parent)->m_wndView.ResizeImage(IMG_DIMX, IMG_DIMY, false);
		m_RenderCheck->SetCheck(0);
		m_RenderCheck->EnableWindow(FALSE);
		isRender = false;
	}
	::CAnnotationTool::FocusOnRichEdit();
	return;
}

void CAnnotationTool::OnBnClickedCheckRender()
{
	CButton* m_RenderCheck = (CButton*)CAnnotationTool::GetDlgItem(IDC_CHECK_RENDER);
	int isRenderChecked = m_RenderCheck->GetCheck();

	// Fit to size is selected
	if (isRenderChecked == 1)
	{
		// Render activated
		isRender = true;
	}
	else
	{
		// Render deactivated
		isRender = false;
	}

	::CAnnotationTool::OnBnClickedCheckFit();
	return;
}

void CAnnotationTool::OnBnClickedCheckAutoSave()
{
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel()!=LB_ERR)
		::CAnnotationTool::FocusOnRichEdit();
	return;
}

void CAnnotationTool::OnTcnSelchangeTabRichedit(NMHDR *pNMHDR, LRESULT *pResult)
{
	if (!imagesLoaded || m_Cur == -1)
		return;

	// Update previous caption
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel() != LB_ERR)
		::CAnnotationTool::UpdateTextEntry();

	// Open new caption
	CString filepath(m_FileList[m_Enum.at(m_Cur)].c_str());
	::CAnnotationTool::OpenRichEdit(filepath);

	// Set focus
	::CAnnotationTool::FocusOnRichEdit();

	// Update last active tab
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	m_TabLastSel = m_TabCtrl->GetCurSel();
	*pResult = 0;

	return;
}

void CAnnotationTool::OnTcnSelchangeTabRichedit(/* OVERLOADED TO TAKE NO ARGUMENTS */)
{
	if (!imagesLoaded || m_Cur == -1)
		return;

	// Update previous caption
	CListBox* m_ListBox = (CListBox*)CAnnotationTool::GetDlgItem(IDC_LIST_IMAGELIST);
	if (m_ListBox->GetCurSel() != LB_ERR)
		::CAnnotationTool::UpdateTextEntry();

	// Open new caption
	CString filepath(m_FileList[m_Enum.at(m_Cur)].c_str());
	::CAnnotationTool::OpenRichEdit(filepath);

	// Set focus
	::CAnnotationTool::FocusOnRichEdit();

	// Update last active tab
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	m_TabLastSel = m_TabCtrl->GetCurSel();

	return;
}

void CAnnotationTool::OnCbnSelchangeSortListComboBox()
{
	if (!imagesLoaded)
		return;
	
	::CAnnotationTool::UpdateList();

	CComboBox* m_ComboBox = (CComboBox*)CAnnotationTool::GetDlgItem(IDC_SORTLIST_COMBOBOX);
	::CAnnotationTool::SortFileList((sortModes)m_ComboBox->GetCurSel(), (size_t)m_FileList.size());

	return;
}

void CAnnotationTool::TabRicheditNextTab()
{
	CTabCtrl* m_TabCtrl = (CTabCtrl*)CAnnotationTool::GetDlgItem(IDC_TAB_RICHEDIT);
	switch(m_TabCtrl->GetCurSel())
	{
	case Caption:
		m_TabCtrl->SetCurSel(1);
		break;
	case Reference:
		m_TabCtrl->SetCurSel(2);
		break;
	case Reminds:
		m_TabCtrl->SetCurSel(0);
		break;
	}

	CAnnotationTool::OnTcnSelchangeTabRichedit();

	return;
}
void CAnnotationTool::OnBnClickedButtonTextprocess()
{
	CButton* textbutton = (CButton*)CAnnotationTool::GetDlgItem(IDC_BUTTON_TEXTPROCESS);
	CString buttonstring;
	if(textprocess == NULL)	//Create the dialog
	{
		textprocess = new CTextProcess(this);
		if(textprocess->Create()!=TRUE)
		{
			::AfxMessageBox(CString("Failed to create text processing dialog"), MB_OK, 0);
		}
		else
		{
			//Set the window position based on CAnnotation
			RECT lprect;
			CAnnotationTool::GetWindowRect(dlg_lprect);
			textprocess->GetWindowRect(&lprect);
			lprect.right = (lprect.right-lprect.left)+dlg_lprect->right+1;
			lprect.left = dlg_lprect->right + 1;
			lprect.bottom = (lprect.bottom-lprect.top)+dlg_lprect->top;
			lprect.top = dlg_lprect->top;
			textprocess->MoveWindow(&lprect, 1);
			textprocess->ShowWindow(1);

			//Set the freetext of the window
			CEdit* richedit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_EDIT_CAPTION);
			CString freetext;
			richedit->GetWindowTextW(freetext);
			textprocess->AssignStringFreeText(freetext);
			textbutton->SetWindowTextW(CString("Hide Process"));
		}
	}
	else	//If dialog already created, set to show or not show
	{
		textbutton->GetWindowTextW(buttonstring);
		if(buttonstring.Compare(CString("Show Process"))==0)
		{
			textprocess->ShowWindow(1);
			textbutton->SetWindowTextW(CString("Hide Process"));
		}
		else
		{
			textprocess->ShowWindow(0);
			textbutton->SetWindowTextW(CString("Show Process"));
		}
	}
	return;
}

//Get the filelist
vector<string> CAnnotationTool::GetFileList(void)
{
	return m_FileList;
}

//Append keyword to the image
void	CAnnotationTool::AppendKeyword(std::string keyword)
{
	CEdit* edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_IMAGEANNOTATION_KEYWORDS);
	CString keywords;
	edit->GetWindowTextW(keywords);
	keywords += (CString(keyword.c_str())+CString("\r\n"));
	edit->SetWindowTextW(keywords);
	return;
}

//Delete a keyword
void CAnnotationTool::DeleteKeyword(void)
{
	CEdit* edit = (CEdit*)CAnnotationTool::GetDlgItem(IDC_IMAGEANNOTATION_KEYWORDS);
	CString multicharstring;
	edit->GetWindowTextW(multicharstring);
	if(multicharstring.GetLength()<=0)
		return;

	//Get the current select content to determine the start and end position to be deleted
	int selectstart, selectend;
	edit->GetSel(selectstart, selectend);
	CT2CA ascii(multicharstring);
	string asciistring(ascii);
	bf.RemoveEnter(asciistring);
	unsigned int startposition = bf.SearchBackward('\n', asciistring.c_str(), (unsigned int)selectstart, (unsigned int)asciistring.size());
	if(startposition==UINT_MAX)
		startposition = 0;
	else
		startposition++;
	unsigned int endposition = bf.SearchForward('\n', asciistring.c_str(), (unsigned int)selectend, (unsigned int)asciistring.size());
	if(endposition==UINT_MAX)
		endposition = (unsigned int)asciistring.size();
	else
		endposition++;

	//Delete the string
	asciistring.erase(startposition, endposition-startposition);
	edit->SetWindowTextW(CString(asciistring.c_str()));
	
	return;
}

//Close the dialog
void CAnnotationTool::OnClose()
{
	CDialog::OnClose();
	if(textprocess!=NULL)
		textprocess->CloseDialog();
}

//Save the list into the database, if image already existed, update the text entry
void CAnnotationTool::OnBnClickedImageannotationSavetodatabase()
{

	CImageAnnotation imagedatabase;
	vector<string>::iterator iterator;
	CLinguisticProcessing* linguisticprocessing;
	try
	{
		imagedatabase.Open();
	}
	catch(CDBException *e)
	{
		e->ReportError();
		return;
	}

	//Set corpus
	//vector<string> linguisticcorpus;
	//vector<unsigned int> corpusfrequency;
	int yesnolinguistic = ::AfxMessageBox(CString("Incorporated linguistic features?\n\rIf yes, please select the file containing the corpus after the click YES\n\rPlease provide the corpus in the following format:\n\rKeyword1\tFrequency\n\rKeyword2\tFrequency\n\r..."),  MB_YESNO, 0);
	if(yesnolinguistic == 0)	//Failed to show the dialog
	{
		return;
	}
	if(yesnolinguistic == IDYES)	//Calculate linguistic features
	{
		//Set the corpus
		try
		{
			CFileDialog filedialog(TRUE, 0, 0, OFN_FILEMUSTEXIST, _T("(Text file *.txt)|*.txt||"));
			INT_PTR selectstatus = filedialog.DoModal();
			if(selectstatus==FALSE)
			{
				::AfxMessageBox(_T("Failed to open dialog"), MB_OK, 0);
				return;
			}
			CString tempstring = filedialog.GetFileName();
			CT2CA asciistring(tempstring);
			linguisticprocessing = new CLinguisticProcessing(string(asciistring), LOGSPACE);
			//Save the corpus
			linguisticprocessing->SaveCorpusToFile(string(HOMEDIRECTORY)+string("data\\corpus.txt"));
		}
		catch(string exceptionmessage)
		{
			::AfxMessageBox(CString(exceptionmessage.c_str()), MB_OK, 0);
			return;
		}
	}

	for(iterator=m_FileList.begin(); iterator!=m_FileList.end(); iterator++)
	{
		string filepath(*iterator);
		//Requery the database
		imagedatabase.m_strFilter = (CString("Image LIKE '")+(CString(filepath.c_str())+CString("'")));
		imagedatabase.Requery();

		if(imagedatabase.IsEOF())	//If record not exsited, add it
		{
			if(!((CChildFrame*)m_Parent)->m_wndView.OnImageOpen(CString(filepath.c_str()), CString("Temporal")))	//If failed to open the image
				continue;

			imagedatabase.AddNew();
			string captionfile = string(filepath.c_str(), filepath.size()-4)+string(".txt");
			string referencefile = string(filepath.c_str(), filepath.size()-4)+string(".reference.txt");
			string remindsoffile = string(filepath.c_str(), filepath.size()-4)+string(".remindsof.txt");
			string keywordfile = string(filepath.c_str(), filepath.size()-4)+string(".keyword.txt");
			imagedatabase.m_Image = CStringA(filepath.c_str());
			imagedatabase.m_Caption = CStringA(bf.LoadFromFile(captionfile).c_str());
			imagedatabase.m_Reference = CStringA(bf.LoadFromFile(referencefile).c_str());
			imagedatabase.m_RMO = CStringA(bf.LoadFromFile(remindsoffile).c_str());
			imagedatabase.m_Keywords = CStringA(bf.LoadFromFile(keywordfile).c_str());

			//Obtain and save the image features
			vector<vector<double>> multiscalefeature = ((CChildFrame*)m_Parent)->m_wndView.GetImageWaveletFeature(4, 3, 3);
			bf.SaveDataAsBinary(multiscalefeature, "c:\\temp.dat");		//Save into a file
			CFile cfile;
			try	//Reopen the file and save the data into a global memory and inseart into the database
			{
				cfile.Open(CString("c:\\temp.dat"), CFile::modeRead);
				HGLOBAL globalmemory = GlobalAlloc(GPTR, (SIZE_T)cfile.GetLength());
				imagedatabase.m_Feature.m_hData = GlobalLock(globalmemory);
				cfile.Read(imagedatabase.m_Feature.m_hData, (UINT)cfile.GetLength());
				imagedatabase.m_Feature.m_dwDataLength = (UINT)cfile.GetLength();
				cfile.Close();
				imagedatabase.SetFieldDirty(&imagedatabase.m_Feature, 1);
				imagedatabase.SetFieldNull(&imagedatabase.m_Feature, 0);
				imagedatabase.Update();
				GlobalUnlock(globalmemory);
				GlobalDiscard(globalmemory);
			}
			catch(CException* e)
			{
				e->ReportError();
				return;
			}
		}
		else	//If record existed, update text entry and linguistic features
		{
			imagedatabase.Edit();
			//Text entry
			string captionfile = string(filepath.c_str(), filepath.size()-4)+string(".txt");
			string referencefile = string(filepath.c_str(), filepath.size()-4)+string(".reference.txt");
			string remindsoffile = string(filepath.c_str(), filepath.size()-4)+string(".remindsof.txt");
			string keywordfile = string(filepath.c_str(), filepath.size()-4)+string(".keyword.txt");
			imagedatabase.m_Caption = CStringA(bf.LoadFromFile(captionfile).c_str());
			imagedatabase.m_Reference = CStringA(bf.LoadFromFile(referencefile).c_str());
			imagedatabase.m_RMO = CStringA(bf.LoadFromFile(remindsoffile).c_str());
			imagedatabase.m_Keywords = CStringA(bf.LoadFromFile(keywordfile).c_str());
			//Save the database
			try
			{
				imagedatabase.Update();
			}
			catch(CException* e)
			{
				e->ReportError();
				return;
			}
		}

		//Update the linguistic features
		if(yesnolinguistic == IDYES)
		{
			//Linguistic features from captions
			try
			{
				string captionfile = string(filepath.c_str(), filepath.size()-4)+string(".txt");
				vector<double> linguisticfeature = linguisticprocessing->GetLinguisticFeature(string(imagedatabase.m_Caption.GetBuffer()));
				bf.SaveDataAsBinary(linguisticfeature, string("c:\\temp.dat"));
			}
			catch(string exceptionmessage)
			{
				::AfxMessageBox(CString(exceptionmessage.c_str()), MB_OK, 0);
				return;
			}
			try
			{
				imagedatabase.Requery();
				imagedatabase.MoveFirst();
				imagedatabase.Edit();
				CFile cfile;
				cfile.Open(CString("c:\\temp.dat"), CFile::modeRead);
				HGLOBAL globalmemory = GlobalAlloc(GPTR, (SIZE_T)cfile.GetLength());
				imagedatabase.m_Linguistic.m_hData = GlobalLock(globalmemory);
				cfile.Read(imagedatabase.m_Linguistic.m_hData, (UINT)cfile.GetLength());
				imagedatabase.m_Linguistic.m_dwDataLength = (UINT)cfile.GetLength();
				cfile.Close();
				imagedatabase.SetFieldDirty(&imagedatabase.m_Linguistic, 1);
				imagedatabase.SetFieldNull(&imagedatabase.m_Linguistic, 0);
				imagedatabase.Update();
				GlobalUnlock(globalmemory);
				GlobalDiscard(globalmemory);
			}
			catch(CException* e)
			{
				e->ReportError();
				return;
			}
		}
		//Update the database
	}

	imagedatabase.Close();
	return;
}

void CAnnotationTool::OnBnClickedImageannotationSearchimage()
{
	if(searchimage==NULL)
	{
		//Create the dialog safely
		searchimage = new CSearchImage(this);
		if(searchimage->Create()==FALSE)
		{
			::AfxMessageBox(CString("Failed to create dialog!"), MB_OK, 0);
			return;
		}
		else
		{
			searchimage->ShowWindow(TRUE);
		}
	}
	else
	{
		searchimage->ShowWindow(TRUE);
	}
}

//Set the search list
void CAnnotationTool::SetSearch()
{
	if(searchimage!=NULL)
	{
		searchimage->querylist = m_FileList;
	}
	return;
}
